#!/usr/bin/python
# -*- coding: UTF-8 -*-
from __future__ import absolute_import
from __future__ import unicode_literals
import os
import cv2
import time
import traceback
import numpy as np


# 下方大部分函数都有一个参数就是ddepth,即：图像的深度，可以理解为数据类型
# 图像深度是指存储每个像素值所用的位数，例如cv2.CV_8U，指的是8位无符号数，取值范围为0~255，超出范围则会被截断
# （截断指的是，当数值大于255保留为255，当数值小于0保留为0，其余不变）。
def laplacian_edge(image_input, kernel_size):
    """
    説明：对图像中的阶跃性边缘点定位准确， 对噪声非常敏感，丢失一部分边缘的方向信息， 造成一些不连续的检测边缘
    """
    if image_input.ndim == 3:
        temp_image = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)
        laplacian_image = cv2.Laplacian(temp_image, cv2.CV_16S, ksize=kernel_size)
    else:
        laplacian_image = cv2.Laplacian(image_input, cv2.CV_16S, ksize=kernel_size)
    return cv2.convertScaleAbs(laplacian_image)


def sobel_edge(image_input, kernel_size, direction='X direction'):
    if direction == 'X direction':
        sobel_image = cv2.Sobel(image_input, cv2.CV_16S, 0, 1, ksize=kernel_size)
    elif direction == 'Y direction':
        sobel_image = cv2.Sobel(image_input, cv2.CV_16S, 1, 0, ksize=kernel_size)
    else:
        sobel_image_x = cv2.Sobel(image_input, cv2.CV_16S, 0, 1, ksize=kernel_size)
        sobel_image_y = cv2.Sobel(image_input, cv2.CV_16S, 1, 0, ksize=kernel_size)
        sobel_image = cv2.addWeighted(sobel_image_x, 0.5, sobel_image_y, 0.5, 0)  # 两个方向梯度加权求和
    return cv2.convertScaleAbs(sobel_image)


def prewitt_edge(image_input, direction='X direction'):
    kernel_x = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)
    kernel_y = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)
    if direction == 'X direction':
        prewitt_image = cv2.filter2D(image_input, cv2.CV_16S, kernel_x)
    elif direction == 'Y direction':
        prewitt_image = cv2.filter2D(image_input, cv2.CV_16S, kernel_y)
    else:
        prewitt_image_x = cv2.filter2D(image_input, cv2.CV_16S, kernel_x)
        prewitt_image_y = cv2.filter2D(image_input, cv2.CV_16S, kernel_y)
        prewitt_image = cv2.addWeighted(prewitt_image_x, 0.5, prewitt_image_y, 0.5, 0)  # 两个方向梯度加权求和
    return cv2.convertScaleAbs(prewitt_image)


def roberts_edge(image_input, direction='X direction'):
    kernel_x = np.array([[-1, 0], [0, 1]], dtype=int)
    kernel_y = np.array([[0, -1], [1, 0]], dtype=int)
    if direction == 'X direction':
        roberts_image = cv2.filter2D(image_input, cv2.CV_16S, kernel_x)
    elif direction == 'Y direction':
        roberts_image = cv2.filter2D(image_input, cv2.CV_16S, kernel_y)
    else:
        roberts_image_x = cv2.filter2D(image_input, cv2.CV_16S, kernel_x)
        roberts_image_y = cv2.filter2D(image_input, cv2.CV_16S, kernel_y)
        roberts_image = cv2.addWeighted(roberts_image_x, 0.5, roberts_image_y, 0.5, 0)  # 两个方向梯度加权求和
    return cv2.convertScaleAbs(roberts_image)


def canny_edge(image_input, low_th=0, high_th=100):
    return cv2.Canny(image_input, low_th, high_th)


def log_edge(image_input):
    gauss_kernl_size = 3
    laplace_kernel_size = 3
    if image_input.ndim == 3:
        temp_image = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)
        blur_image = cv2.GaussianBlur(temp_image, (gauss_kernl_size, gauss_kernl_size), 0)
        laplace_image = cv2.Laplacian(blur_image, cv2.CV_16S, ksize=laplace_kernel_size)
    else:
        blur_image = cv2.GaussianBlur(image_input, (gauss_kernl_size, gauss_kernl_size), 0)
        laplace_image = cv2.Laplacian(blur_image, cv2.CV_16S, ksize=laplace_kernel_size)
    return cv2.convertScaleAbs(laplace_image)


# if __name__ == "__main__":
#     path = r'C:\Users\admin\Desktop\dt\test.bmp'  # place path to your image here
#     image_cv = cv2.imread(path, -1)
#     gau = log_edge(image_cv)
#     cv2.imshow("Operation", gau)
#     cv2.waitKey(0)
